package com.bosssoft.cloud.wechat.infrastructure.util;

import com.bosssoft.cloud.wechat.infrastructure.enums.ErrEnum;
import com.bosssoft.cloud.wechat.infrastructure.exception.BaseException;
import com.bosssoft.cloud.wechat.infrastructure.exception.BusinessException;
import com.bosssoft.cloud.wechat.infrastructure.exception.SystemException;
import com.bosssoft.cloud.wechat.infrastructure.exception.TPSException;
import lombok.NoArgsConstructor;

import java.lang.reflect.InvocationTargetException;

/**
 * Assert工具类
 *
 * @author wcy create on 2021/7/21 18:10 下午
 */
@NoArgsConstructor
public abstract class Assert {

    public static void isTrue(boolean expression, ErrEnum errEnum) {
        isTrue(expression, errEnum, null);
    }

    public static void isTrue(boolean expression, ErrEnum errEnum, String message) {
        if (errEnum.getCode().startsWith("A"))
            isTrue(expression, errEnum, message, BusinessException.class);
        if (errEnum.getCode().startsWith("B"))
            isTrue(expression, errEnum, message, SystemException.class);
        if (errEnum.getCode().startsWith("C"))
            isTrue(expression, errEnum, message, TPSException.class);
        isTrue(expression, errEnum, message, BaseException.class);
    }

    /**
     * assert isTrue执行方法
     *
     * @param expression 判断条件
     * @param errEnum    错误码enum
     * @param message    message
     * @param clazz      异常类class
     */
    public static void isTrue(
            boolean expression,
            ErrEnum errEnum,
            String message,
            Class<? extends Exception> clazz) {
        if (!expression) {
            Class[] cArg = new Class[]{ErrEnum.class, String.class};
            BaseException e = null;
            try {
                e = (BaseException) clazz.getDeclaredConstructor(cArg).newInstance(errEnum, message);
            } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException instantiationException) {
                instantiationException.printStackTrace();
            }
            if (e != null) throw e;
        }
    }

    public static void notNull(Object object, ErrEnum errEnum) {
        notNull(object, errEnum, null);
    }

    public static void notNull(Object object, ErrEnum errEnum, String message) {
        isTrue(object != null, errEnum, message);
    }

    public static void notOrNull(Object[] object, ErrEnum errEnum) {
        for (Object o : object) {
            if (o != null) return;
        }
        isTrue(false, errEnum);
    }

    public static void notAndNull(Object[] object, ErrEnum errEnum) {
        for (Object o : object)
            if (o == null) isTrue(false, errEnum);
    }

    public static void isNull(Object object, ErrEnum errEnum) {
        isNull(object, errEnum, null);
    }

    public static void isNull(Object object, ErrEnum errEnum, String message) {
        isTrue(object == null, errEnum, message);
    }

    public static void isOrNull(Object[] object, ErrEnum errEnum) {
        for (Object o : object) {
            if (o == null) return;
        }
        isTrue(false, errEnum);
    }

    public static void isAndNull(Object[] object, ErrEnum errEnum) {
        for (Object o : object)
            if (o != null) isTrue(false, errEnum);
    }
}
